package com.fyj.controller;

import com.fyj.pojo.*;
import com.fyj.service.DbaMissionService;
import com.fyj.util.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 钰杰
 * @className DbaController
 * @description VX:FengYJ996
 * @date 2019/12/411:28
 */
@Api(tags = "DBA操作接口")
@RestController
@RequestMapping(value = "/dbacontroller")
public class DbaController {

    @Autowired
    public DbaMissionService dbaMissionService;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 获取所有连接
     *
     * @return
     */
    @ApiOperation(value = "获取所有连接信息", notes = "获取所有连接信息列表")
    @ApiImplicitParam(value = "获取所有连接信息列表")
    @GetMapping(value = "/findLinkManageAll")
    public Result getLinkManageAll() {
        List<LinkManage> linkManageAll = dbaMissionService.getLinkManageAll();
        if (linkManageAll != null && linkManageAll.size() > 0) {
            return new Result(true, ResultCode.SUCCESS_CODE, "获取链接信息库", linkManageAll);
        } else {
            return new Result(false, ResultCode.ERROR_DBA_BAD_CONNECTION_CODE, "获取链接信息库异常", null);
        }
    }

    /**
     * 检测链接
     *
     * @param linkManageId 链接源
     * @param typeid       类型
     * @param mark         请求来源 0：测试，1：源数据库，2：目标数据库
     * @return
     */
    @ApiOperation(value = "测试当前连接信息", notes = "检测是否可连")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "linkManageId", value = "连接编号", required = true, dataType = "Integer",paramType = "path"),
            @ApiImplicitParam(name = "typeid", value = "数据库编号", required = true, dataType = "Integer",paramType = "path"),
            @ApiImplicitParam(name = "mark", value = "当前操作来源", required = true, dataType = "Integer",paramType = "path"),
            @ApiImplicitParam(name = "uuid", value = "本次操作唯一标识符", required = true, dataType = "int",paramType = "path"),
    })
    @GetMapping(value = "/testConnection/{linkManageId}/{typeid}/{mark}")
    public Result testDataBaseConnection(@PathVariable(value = "linkManageId") Integer linkManageId,
                                         @PathVariable(value = "typeid") Integer typeid,
                                         @PathVariable(value = "mark") Integer mark,
                                         @RequestParam(value = "uuid") String uuid) {
        Map<String, String> dataSource = dbaMissionService.DataBaseConnection(linkManageId, typeid);
        if (dataSource != null && dataSource.size() > 0) {
            Map<String, Object> redisKeyMap = new HashMap<>();
            redisKeyMap.put("mark", mark);
            redisKeyMap.put("uuid", uuid);
            redisUtil.addRedisMap(mark + "", uuid, dataSource);
            return new Result(true, ResultCode.SUCCESS_CODE, "当前链接成功!", redisKeyMap);
        } else {
            return new Result(false, ResultCode.ERROR_DBA_BAD_CONNECTION_CODE, "当前链接不可用!", null);
        }
    }

    /**
     * 获取连接下所有数据库
     *
     * @param mark 标识dataSource来源
     * @param uuid 唯一标识
     * @return
     */
    @ApiOperation(value = "获取数据库列表", notes = "获取当前连接下所有数据库信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mark", value = "当前操作来源", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "uuid", value = "本次操作唯一标识符", required = true, dataType = "String")
    })
    @PostMapping(value = "/getAllDatabase/{mark}")
    public Result getAllDatabase(@PathVariable("mark") Integer mark,
                                 @RequestParam("uuid") String uuid) {
        Map<String, String> dataSource = redisUtil.generateDataSource(mark+"", uuid);
        if (dataSource != null && dataSource.size() > 0) {
            ArrayList<String> dataBaseAll = dbaMissionService.getDataBaseAll(dataSource);
            if (dataBaseAll != null && dataBaseAll.size() > 0) {
                return new Result(true, ResultCode.SUCCESS_CODE, "获取链接下数据库列表", dataBaseAll);
            } else {
                return new Result(false, ResultCode.ERROR_DBA_SHOW_DATABASES_CODE, "获取链接下数据库列表失败！", null);
            }
        } else {
            return new Result(false, ResultCode.ERROR_DBA_REDIS_DATASOUTCE_INVALID_CODE, "当前链接已过期!", null);
        }

    }

    /**
     * 获取指定库下所有表信息
     *
     * @param mark         来源
     * @param uuid         操作ID唯一标识
     * @param dataBaseName 指定数据库
     * @return
     */
    @ApiOperation(value = "获取数据表列表", notes = "获取当前数据库下所有数据表信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mark", value = "当前操作来源", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "uuid", value = "本次操作唯一标识符", required = true, dataType = "String"),
            @ApiImplicitParam(name = "dataBaseName", value = "指定查询数据库", required = true, dataType = "String")
    })
    @PostMapping(value = "/getAllTables/{mark}")
    public Result getAllTables(@PathVariable("mark") Integer mark,
                               @RequestParam("uuid") String uuid, @RequestParam("dataBaseName") String dataBaseName) {
        Map<String, String> dataSource = redisUtil.generateDataSource(mark+"", uuid);
        if (dataSource != null && dataSource.size() > 0) {
            ArrayList<String> tablesAll = dbaMissionService.getTablesAll(dataSource, dataBaseName);
            if (tablesAll != null && tablesAll.size() > 0) {
                return new Result(true, ResultCode.SUCCESS_CODE, "获取库下表信息", tablesAll);
            } else {
                return new Result(false, ResultCode.ERROR_DBA_SHOW_TABLES_CODE, "获取数据库下表信息失败！", null);
            }
        } else {
            return new Result(false, ResultCode.ERROR_DBA_REDIS_DATASOUTCE_INVALID_CODE, "当前链接已过期!", null);
        }
    }

    /**
     * 获取指定表中所有字段
     *
     * @param mark      来源
     * @param uuid      操作ID唯一标识
     * @param tableName 指定表
     * @return
     */
    @ApiOperation(value = "获取字段列表", notes = "获取当前数据表中所有字段信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mark", value = "当前操作来源", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "uuid", value = "本次操作唯一标识符", required = true, dataType = "String"),
            @ApiImplicitParam(name = "tableName", value = "指定查询数据表", required = true, dataType = "String")
    })
    @PostMapping(value = "/getFiledAll/{mark}")
    public Result getFiledAll(@PathVariable("mark") Integer mark,
                              @RequestParam("uuid") String uuid, @RequestParam("tableName") String tableName) {
        Map<String, String> dataSource = redisUtil.generateDataSource(mark+"", uuid);
        if (dataSource != null && dataSource.size() > 0) {
            ArrayList<String> filedAll = dbaMissionService.getFiledAll(dataSource, tableName);
            if (filedAll != null && filedAll.size() > 0) {
                return new Result(true, ResultCode.SUCCESS_CODE, "获取表中所有字段", filedAll);
            } else {
                return new Result(false, ResultCode.ERROR_DBA_SHOW_FILEDS_CODE, "获取数据表中字段失败！", null);
            }
        } else {
            return new Result(false, ResultCode.ERROR_DBA_REDIS_DATASOUTCE_INVALID_CODE, "当前链接已过期!", null);
        }
    }

    /**
     * 添加任务细节
     *
     * @param mark
     * @param uuid
     * @param missionDetail
     * @return
     */
    @ApiOperation(value = "添加任务细节", notes = "将选择任务细节添加")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mark", value = "当前操作来源", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "uuid", value = "本次操作唯一标识符", required = true, dataType = "String"),
            @ApiImplicitParam(name = "missionDetail", value = "任务详情实体", required = true, dataType = "MissionDetail")
    })
    @PostMapping(value = "/addMissionDetail/{mark}")
    public Result addMissionDetail(@PathVariable("mark") Integer mark,
                                   @RequestParam("uuid") String uuid, @RequestBody MissionDetail missionDetail) {
        Map<String, String> dataSource = redisUtil.generateDataSource(mark+"", uuid);
        String driver = dataSource.get("driver");
        if (dataSource != null && dataSource.size() > 0) {
            String detailKey = dbaMissionService.addMissionDetail(dataSource, missionDetail, driver);//detailKey用来保存在任务表
            if (detailKey != null && detailKey.length() > 0) {
                boolean b = redisUtil.addMissionKey(mark+"", uuid, detailKey);
                if (b) {
                    return new Result(true, ResultCode.SUCCESS_CODE, "任务详情添加成功", detailKey);
                } else {
                    return new Result(false, ResultCode.ERROR_DBA_REDIS_DATASOUTCE_INVALID_CODE, "当前链接已过期!", null);
                }
            } else {
                return new Result(false, ResultCode.ERROR_DBA_SHOW_FILEDS_CODE, "任务详情添加失败！", null);
            }
        } else {
            return new Result(false, ResultCode.ERROR_DBA_REDIS_DATASOUTCE_INVALID_CODE, "当前链接已过期!", null);
        }
    }

    /**
     * 添加任务
     *
     * @param myMission
     * @param uuid
     * @return
     */
    @ApiOperation(value = "添加任务", notes = "将本次任务加入记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uuid", value = "本次操作唯一标识符", required = true, dataType = "String"),
            @ApiImplicitParam(name = "MyMission", value = "任务实体", required = true, dataType = "MyMission")
    })
    @PostMapping(value = "/addMission")
    public Result addMission(@RequestBody MyMission myMission, @RequestParam("uuid") String uuid) {
        int userid = 1;                 //提取UserId
        HashMap<String, String> missionKey = redisUtil.getMissionKey(uuid);
        if (missionKey != null && missionKey.size() > 0) {
            String sourceKey = missionKey.get("sourceKey");
            String targetKey = missionKey.get("targetKey");
            myMission.setSourceInfo(sourceKey);
            myMission.setTarGetInfo(targetKey);
            boolean addMission = dbaMissionService.addMission(myMission, userid);
            if (addMission) {
                return new Result(true, ResultCode.SUCCESS_CODE, "任务提交成功", null);
            } else {
                return new Result(false, ResultCode.ERROR_DBA_COMMIT_MISSION_CODE, "任务提交失败", null);
            }
        } else {
            return new Result(false, ResultCode.ERROR_DBA_COMMIT_MISSION_INVALID_CODE, "此次任务已失效", null);

        }


    }

    /**
     * 开始迁移任务
     *
     * @param missionNumber 任务编号
     * @return
     */
    @ApiOperation(value = "开始任务", notes = "开始迁移任务")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "missionNumber", value = "任务标示编号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "threadCount", value = "启动线程数", required = true, dataType = "String")
    })
    @PostMapping(value = "/startMigration")
    public Result startMigration(@RequestParam("missionNumber") String missionNumber,
                                 @RequestParam("threadCount") String threadCount
    ) {
        int code = dbaMissionService.transferData(missionNumber, Integer.parseInt(threadCount));
        if (code == 0) {
            return new Result(true, ResultCode.SUCCESS_CODE, "数据迁移已完成", null);
        } else if (code == 5210) {
            return new Result(false, ResultCode.ERROR_DBA_NAMING_REPETITION_CODE, "目标数据库表名重复！", null);
        } else {
            return new Result(false, ResultCode.ERROR_DBA_FAIL_MIGRATION_CODE, "数据迁移失败！", null);
        }

    }

    /**
     * 查看工作情况
     *
     * @param missionNumber
     * @return
     */
    @ApiOperation(value = "查看工作进度")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "missionNumber", value = "任务标示编号", required = true, dataType = "String")})
    @PostMapping(value = "/checkWorkProgress")
    public Result checkWorkProgress(@RequestParam("missionNumber") String missionNumber) {
        int work = dbaMissionService.checkWork(missionNumber);
        if (work == 0) {
            return new Result(true, ResultCode.SUCCESS_CODE, "任务传输完成", work);
        }
        return new Result(true, ResultCode.SUCCESS_CODE, "任务传输中...", work);
    }


    /**
     * 获取任务列表信息
     *
     * @return
     */
    @ApiOperation(value = "获取任务列表信息", notes = "获取所有任务信息列表")
    @ApiImplicitParam(value = "获取所有任务信息列表")
    @GetMapping(value = "/getMissionAll")
    public Result getMissionAll() {
        List<MyMission> allMission = dbaMissionService.getAllMission();
        if (allMission != null) {
            return new Result(true, ResultCode.SUCCESS_CODE, "任务列表", allMission);
        } else {
            return new Result(false, ResultCode.ERROR_DBA_SHOW_MISSION_CODE, "获取任务列表失败", null);
        }
    }

}
